using System;
using System.Collections.Generic;
using System.Text;
using System.Collections;

namespace Axe.Collections
{
    [Serializable]
    public class SyncList<T> : IList<T>, ICollection<T>,
        IEnumerable<T>, IList, ICollection, IEnumerable
    {
        private List<T> Container;
        private object SyncObj = new object();

        public List<T> Unsafe
        {
            get
            {
                return Container;
            }
        }

        public SyncList()
        {
            Container = new List<T>();
        }

        public SyncList(IEnumerable<T> collection)
        {
            Container = new List<T>(collection);
        }

        public SyncList(int InitialCapacity)
        {
            Container = new List<T>(InitialCapacity);
        }

        public void ForEach(Action<T> action)
        {
            lock(SyncObj)
            {
                Container.ForEach(action);
            }
        }

        #region IList<T> Members

        public int IndexOf(T item)
        {
            return Container.IndexOf(item);
        }

        public void Insert(int index, T item)
        {
            lock(SyncObj)
            Container.Insert(index, item);
        }

        public void RemoveAt(int index)
        {
            lock(SyncObj)
                Container.RemoveAt(index);
        }

        public T this[int index]
        {
            get
            {
                lock(SyncObj)
                    return Container[index];
            }
            set
            {
                lock(SyncObj)
                    Container[index] = value;
            }
        }

        #endregion

        #region ICollection<T> Members

        public void Add(T item)
        {
            lock(SyncObj)
                Container.Add(item);
        }

        public void Clear()
        {
            lock(SyncObj)
                Container.Clear();
        }

        public bool Contains(T item)
        {
            lock(SyncObj)
                return Container.Contains(item);
        }

        public void CopyTo(T[] array, int arrayIndex)
        {
            lock(SyncObj)
                Container.CopyTo(array, arrayIndex);
        }

        public int Count
        {
            get { return Container.Count; }
        }

        public bool IsReadOnly
        {
            get { return false; }
        }

        public bool Remove(T item)
        {
            lock(SyncObj)
                return Container.Remove(item);
        }

        #endregion

        #region IEnumerable<T> Members

        public IEnumerator<T> GetEnumerator()
        {
            return Container.GetEnumerator();
        }

        #endregion

        #region IEnumerable Members

        IEnumerator IEnumerable.GetEnumerator()
        {
            return Container.GetEnumerator();
        }

        #endregion

        #region ICollection Members

        public void CopyTo(Array array, int index)
        {
            lock(SyncObj)
                (Container as ICollection).CopyTo(array, index);
        }

        public bool IsSynchronized
        {
            get { return true; }
        }

        public object SyncRoot
        {
            get { return SyncObj; }
        }

        #endregion

        #region IList Members

        int IList.Add(object value)
        {
            throw new Exception("The method or operation is not implemented.");
        }

        void IList.Clear()
        {
            throw new Exception("The method or operation is not implemented.");
        }

        bool IList.Contains(object value)
        {
            throw new Exception("The method or operation is not implemented.");
        }

        int IList.IndexOf(object value)
        {
            throw new Exception("The method or operation is not implemented.");
        }

        void IList.Insert(int index, object value)
        {
            throw new Exception("The method or operation is not implemented.");
        }

        bool IList.IsFixedSize
        {
            get { throw new Exception("The method or operation is not implemented."); }
        }

        bool IList.IsReadOnly
        {
            get { throw new Exception("The method or operation is not implemented."); }
        }

        void IList.Remove(object value)
        {
            throw new Exception("The method or operation is not implemented.");
        }

        void IList.RemoveAt(int index)
        {
            throw new Exception("The method or operation is not implemented.");
        }

        object IList.this[int index]
        {
            get
            {
                throw new Exception("The method or operation is not implemented.");
            }
            set
            {
                throw new Exception("The method or operation is not implemented.");
            }
        }

        #endregion
    }
}
